package org.web.datajpa.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
@Aspect
@Slf4j
public class HttpAspect {
    // 定义切点(任意方法，任意输入输出参数)
    @Pointcut("execution(public * org.web.datajpa.api.StudentApiController.*(..))")
    public void log() {
    }
    // 前置通知，使用Joinpoint接口作为参数获得目标对象信息
    @Before("log()")
    public void doBefore() {
        log.info("准备开始执行api。。。");
    }
    // 后置（最终）通知
    @After("log()")
    public void doAfter() {
        log.info("执行api结束准备返回");
    }

    // 在AfterReturning中，我们可以访问到方法的返回值,在After之前执行（后置返回通知）
    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        log.info("response={}", object.toString());
    }

    // 获取方法的执行耗时,环绕通知，可以自定义执行顺序
    @Around("log()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object object = joinPoint.proceed(joinPoint.getArgs());
        stopWatch.stop();
        long totalTimeMillis = stopWatch.getTotalTimeMillis();
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();

        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        log.info("------执行{}方法,用时：{}", methodName, totalTimeMillis);
        return object;
    }
}
